package com.zhupf.zhupfutil.util;

import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.*;

/**
 * poi 导出工具
 */
public class ExportUtil {

    public static void xlsExport(HttpServletResponse response, String sheetName, List<?> list, String[] columns, String[] title, Map<Integer, Integer> widthMap) {
        try {
            HSSFWorkbook wb = getHSSFWorkbook(sheetName, list, columns, title, widthMap);
            setResponseHeader(response, sheetName);
            OutputStream os = response.getOutputStream();
            wb.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            try {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            String suffixName = fileSuffixName();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + new String(("_" + suffixName + ".xls").getBytes(), "iso-8859-1"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public  static String fileSuffixName() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
        String dateString = formatter.format(new Date());
        return dateString;
    }

    /**
     * @param sheetName 导出文件名
     * @param list      导出内容
     * @param columns   导出对象的字段
     * @param title     表头名
     * @param widthMap  列的宽度设置
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbook(String sheetName, List<?> list, String[] columns, String[] title, Map<Integer, Integer> widthMap) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        // 第一步，创建一个HSSFWorkbook，对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();

        // 第二步，在workbook中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet(sheetName);

        // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
        HSSFRow row = sheet.createRow(0);

        // 第四步，创建单元格，并设置值表头 设置表头居中,在这里面可以设置对应样式
        HSSFCellStyle style = wb.createCellStyle();
        style.setWrapText(true);

        // 设置单元格宽度
        setSheetWidth(sheet, widthMap);

        // 声明列对象
        HSSFCell cell = null;
        //创建标题
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }
        String[][] content = new String[list.size()][columns.length];
        for (int i = 0; i < list.size(); i++) {
            Class clazz = list.get(i).getClass();
            for (int j = 0; columns != null && j < columns.length; j++) {
                String name = upperCaseFirstOne(columns[j]);
                Method method = clazz.getMethod(name);
                method.setAccessible(true);
                Object obj = method.invoke(list.get(i));
                if (obj == null || obj.equals("null")) {
                    obj = "";
                }
                content[i][j] = obj.toString();
            }
        }
        // 将查询到的数据设置到sheet对应的单元格中
        for (int i = 0; i < content.length; i++) {
            row = sheet.createRow(i + 1);
            for (int j = 0; j < content[i].length; j++) {
                //将内容按顺序赋给对应的列对象
                row.createCell(j).setCellValue(content[i][j]);
            }
        }
        return wb;
    }

    private static void setSheetWidth(HSSFSheet sheet, Map<Integer, Integer> widthMap) {
        if (!CollectionUtils.isEmpty(widthMap)) {
            for (Map.Entry<Integer, Integer> entry : widthMap.entrySet()) {
                sheet.setColumnWidth(entry.getKey(), entry.getValue());
            }
        }
    }

    private static String upperCaseFirstOne(String origin) {
        StringBuffer sb = new StringBuffer(origin);
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        sb.insert(0, "get");
        return sb.toString();
    }
}
